import type { Metadata } from "next"; import Link from "next/link"; import { notFound, permanentRedirect } from "next/navigation"; import { BookOpen, Download, History } from "lucide-react"; import { getLocale } from "@/lib/i18n/server"; import { fmtDate, fmtInt, href, t, type Locale } from "@/lib/i18n"; import { findRedirect, getPaper } from "@/lib/papers/queries"; import { parseIdentifier } from "@/lib/papers/identifiers"; import { citationApa, citationChicago } from "@/lib/papers/citation"; import { citable, jsonLd, scholarMeta } from "@/lib/papers/meta"; import type { PaperFull } from "@/lib/papers/types"; import { AuthorsLine, StatusChips } from "@/components/paper-items"; import { CiteMenu } from "@/components/cite-menu"; import { ViewBeacon } from "@/components/view-beacon"; import { APP_URL } from "@/lib/env"; export const revalidate = 120; async function load(id: string) { const parsed = parseIdentifier(id); const p = await getPaper(id); if (!p) { const r = await findRedirect(`/papers/${id}`); if (r) permanentRedirect(r.to_path); notFound(); } if (parsed && parsed.slug !== id) permanentRedirect(`/papers/${parsed.slug}`); return p; } export async function generateMetadata({ params }: { params: Promise<{ id: string }> }): Promise { const { id } = await params; const p = await getPaper(id); if (!p) return {}; const other = scholarMeta(p); return { title: `${p.identifier} · ${p.title}`, description: p.abstract[0]?.slice(0, 300), alternates: { canonical: `/papers/${p.slug}`, languages: { en: `/papers/${p.slug}`, fr: `/fr/papers/${p.slug}` } }, openGraph: { type: "article", title: p.title, description: p.abstract[0]?.slice(0, 300), url: `${APP_URL}/papers/${p.slug}`, images: [`/api/preview/${p.slug}.png`] }, other }; } function Section({ id, title, children }: { id: string; title: string; children: React.ReactNode }) { return

{title}

{children}
; } function Pairs({ items, locale }: { items: { title: string; description: string; kind?: string }[]; locale: Locale }) { return
{items.map((c, i) =>
{c.kind ? {c.kind} : null}{c.title}
{c.description}
)}
; } const lname = (x: { name_en: string; name_fr: string }, locale: Locale) => (locale === "fr" ? x.name_fr : x.name_en); export default async function PaperPage({ params }: { params: Promise<{ id: string }> }) { const { id } = await params; const locale = await getLocale(); const d = t(locale); const p: PaperFull = await load(id); const c = citable(p, locale); const apa = citationApa(c), chicago = citationChicago(c); const pdfUrl = p.has_pdf && p.file_id ? `/api/files/${p.file_id}/${p.slug}-${p.version_label ?? "current"}.pdf` : null; const abstract = locale === "fr" && p.abstract_fr?.length ? p.abstract_fr : p.abstract; const frOnly = locale === "fr" && !p.abstract_fr?.length; const ld = jsonLd(p); return (